package com.wehealth.biz_ecg.ui;

import static com.wehealth.three.lib_connect.constant.ConstantKey.USER_ECG_IS_RESULT;
import static com.wehealth.three.lib_connect.constant.ConstantKey.USER_ECG_SEARCH_TYPE;
import static com.wehealth.three.lib_connect.constant.ConstantKey.adb_command_dir;
import static com.wehealth.three.lib_connect.constant.ConstantKey.adb_command_typec;
import static com.wehealth.three.lib_connect.utils.FileUtils.writeContentToFile;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import androidx.databinding.DataBindingUtil;

import com.wehealth.biz_ecg.R;
import com.wehealth.biz_ecg.databinding.LayoutEcgMeasurePopBinding;
import com.wehealth.biz_ecg.databinding.SurfaceMeasureBinding;
import com.wehealth.biz_ecg.dialog.BlueToothDeviceListDialog;
import com.wehealth.biz_ecg.dialog.LoadingDialog;
import com.wehealth.ecg.jni.filter.EcgFilter;
import com.wehealth.ecg.jni.heartrate.EcgHRDetect;
import com.wehealth.three.lib_connect.constant.ConstantKey;
import com.wehealth.three.lib_connect.device.usbdevice.UsbSerialThread;
import com.wehealth.three.lib_connect.device.usbdevice.configure.UsbSerialProber;
import com.wehealth.three.lib_connect.device.usbdevice.driver.UsbSerialDriver;
import com.wehealth.three.lib_connect.device.usbdevice.port.UsbSerialPort;
import com.wehealth.biz_ecg.helper.SaveFile24HThread;
import com.wehealth.biz_ecg.helper.SaveFileAutoThread;
import com.wehealth.biz_ecg.helper.SaveFileManualThread;
import com.wehealth.three.lib_connect.base.EcgBaseActivity;
import com.wehealth.three.lib_connect.utils.MainHandler;
import com.wehealth.three.lib_connect.utils.StringUtils;
import com.wehealth.three.lib_connect.utils.PreferenceUtils;
import com.wehealth.three.lib_connect.device.bluetoothdevice.BleConnectThread;
import com.wehealth.three.lib_connect.device.bluetoothdevice.BleDataListener;
import com.wehealth.three.lib_connect.device.bluetoothdevice.kdevice.BleBoothToothHelper;
import com.wehealth.three.lib_connect.device.bluetoothdevice.kdevice.ClassicBlueToothHelper;
import com.wehealth.three.lib_connect.utils.ClassicBlueUtils;
import com.wehealth.three.lib_connect.utils.SampleDotIntNew;
import com.wehealth.three.lib_connect.utils.SaveLogUtil;
import com.wehealth.three.lib_connect.device.bluetoothdevice.BTConnectStreamThread;
import com.wehealth.three.lib_connect.device.usbdevice.data.ParseOriginEcgData;
import com.wehealth.three.lib_connect.utils.ToastUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public class ECGMeasureActivity extends EcgBaseActivity implements OnClickListener, ParseOriginEcgData.EcgDataGetListener, BleDataListener {
    public static ECGMeasureActivity measureActivity;
    // 0 两者都搜  1 classic  2 ble
    public int searchType = 0;
    //当前usb板子的类型 是二代机 or 三代机
    private int usbType = 2;

    //使用测心电App要选择的连接类型
    private int appConnectType = 1;

    protected boolean bleSaveEnough;

    //保存24小时的数据
    private SaveFile24HThread saveFile24HThread;
    //保存手动测量的数据
    private SaveFileManualThread saveFileManualThread;
    //保存自动测量的数据
    private SaveFileAutoThread saveFileAutoThread;
    //增益是否改变
    private boolean waveGainChangeFlag = false;
    //心电图背景
    private Bitmap backMap;
    //心电波形
    private Bitmap waveMap;
    //绘制心电图使用的数据
    private List<int[]> tempList = new ArrayList<>();

    //从采集设备采集到的绘制实时心电图的数据
    private List<int[]> drawDataList = new ArrayList<>();
    //缓存所有的绘制实时心电图的数据的集合
    public List<int[]> ecgDataBuffer = new LinkedList<>();
    //自动测量时候的数据存储
    private List<int[]> bufferAuto = new ArrayList<>();
    //手动测量的12导的数据
    private List<Integer> buf0, buf1, buf2, buf3, buf4, buf5, buf6, buf7, buf8, buf9, buf10, buf11;
    //24小时测量的数据
    private List<Integer> buffer24H = new LinkedList<>();
    //心电图每个小格子的尺寸
    private final int ECG_SINGLE_SPAN_SIZE = 5;
    //心电标尺的右边距
    private final int ECG_RULER_MARGIN_SIZE = 20;

    //处理的是一些蓝牙通用的逻辑  是否打开蓝牙 ，蓝牙是否可用等等
    private BluetoothAdapter bluetoothAdapter;
    //经典蓝牙模式下的心电数据传输
    private BTConnectStreamThread connectStreamThread;

    private BleConnectThread bleConnThread;

    //usb串口通信的通用功能的处理
    private UsbManager usbManager;
    //usb串口通信下的数据采集和处理
    private UsbSerialThread usbSerialThread;
    //布局绑定控件
    private SurfaceMeasureBinding dataBinding;
    private LayoutEcgMeasurePopBinding popDataBinding;

    //绘制心电图的控件
    private SurfaceHolder surfaceHolder;
    private final String TAG = "ECGMeasure";
    private final String ACTION_USB_PERMISSION = "com.wehealth.electrocardiograph_two_client.USB_PERMISSION";
    private PopupWindow pop;
    private RadioGroup hp_group, ac_group, mc_group, lp_group;
    //每次在缓存中去绘制数据的个数 控制绘制的流畅性
    final static int DRAW_STEP_SIZE = 10;
    //绘制的心电图和屏幕的边距
    final static int SCREEN_MARGIN = 4;
    final static int LEAD_NUM = 12;
    //当前参数控制绘制的心电图的增益 增益是有一个默认的数值 在测量的页面是可以修改的
    private int waveGain = 4;
    // 控制的是当前的纸速  纸速也是有一个默认的数值 ，在测量的页面可以修改
    private int waveSpeed = 0;
    //绘制的心电图的样式   显示模式也是又要给默认的样式 在测量的页面可以修改  是否需要上层应用传递？
    //设置为0, 6ch*2 模式; 为1, 12ch*1模式；   为2， 1ch*1模式
    private int waveDisplayType = 0;
    //控制的是绘制12导的具体哪一个导联
    private int waveSingleDisplaySwitch = 2;

    //2为24小时；1为人工Manual；0为自动 Auto:10秒数据  当前的测量类型 需要上层应用传递参数过来
    private int saveFileType = 1;

    //是否开启起搏 也需要上层应用配置
    private boolean waveIsPace = false;

    //提示导联连接状态的点的x坐标
    private float[] leadX = new float[]{319, 339, 346, 353, 235, 323, 310, 251, 306, 251};//{317, 345, 367, 382, 187, 372, 351, 262, 300, 203}
    //提示导联连接状态的点的y坐标
    private float[] leadY = new float[]{138, 157, 157, 157, 158, 158, 193, 120, 120, 193};//{148, 161, 163, 161, 35, 35, 250, 123, 123, 250}

    //基线是否稳定  0为稳定
    private int baseLineState = -1;

    //当前测试类型要保存数据的次数  500次对应1s
    private int saveFileSecondCount;
    //记录存储数据的时间多少分钟
    public int saveManualMinuteCount = 0;
    //绘制使用的画笔
    Paint mPaint, pacePaint, greenPaint, greyPaint, subGridPaint, topGridPaint, redPaint;
    //音频播放
    private SoundPool soundPool = null;
    //播放的音频对应的id
    private final int[] soundPoolId = new int[4];
    //控制是否播放音频
    private boolean isPlaySound = true;

    //当前的x坐标
    public int currentX;
    //屏幕宽度
    public int screenWidth;
    //屏幕高度
    public int screenHeight;
    //导联的名称
    String[] leadName = {"I", "II", "III", "avR", "avL", "avF", "V1", "V2", "V3", "V4", "V5", "V6"};
    //Surface对应的画板
    private Canvas canvas;
    //具体画心电波形的画板
    private Canvas waveCanvas;
    //调整姿势的图片
    private Bitmap bodyLeadMap;
    //通用加载框
    private ProgressDialog progressDialog;
    ;
    //通过timer定时绘制心电图
    private Timer drawTimer;
    //定时结束蓝牙扫描
    private Timer finishScanTimer = new Timer();
    //具体绘制心电图的task的执行逻辑
    private DrawWaveTimeTask drawWaveTimeTask;

    private FinishScanBlueToothTask finishScanBlueToothTask;

    // 绘制心电图的时候使用的数据  0~ 12 对应的是12个导联的数据 13 是12*1 的那个导联的数据
    private List<Integer> dot0, dot1, dot2, dot3, dot4, dot5, dot6, dot7, dot8, dot9, dot10, dot11, dot13;
    //不管导联状态，直接跳过，进入心电曲线画图
    private boolean bodyLeadStateSkip = false;
    //静态分析库需要的参数
    private EcgFilter ecgFilter;
    private EcgHRDetect hrDetect;
    private short FilterBase, FilterMC, FilterAC, FilterLP;
    LoadingDialog loadingDialog;
    //保存文件标识
    private boolean isSaveFile = false;
    //标识没有给导联的连接状态
    protected boolean[] bodyLeaData = new boolean[]{true, true, true, true, true, true, true, true, true, false};
    //显示测量时间的控件
    private int timeSecondCount, timeMinuteCount, timeHourCount;
    //是否重新绘制背景、心电曲线
    private static boolean isRestartDraw = false;

    private float bodyImgW, bodyImgH, percentH, bodyPercentW, side;
    //用户的信息
    private String patientId = "";
    private String patientName = "";
    private int patientAge = 0;
    private int patientGender = 0;

    //导联脱落标识
    private boolean bodyLeadStateOff = false;
    //绘制开关
    private static boolean isDrawECGWave = false;


    //加载动态库
    static {
        System.loadLibrary("ecglib");
    }

    //记录获取数据的次数
    private int saveCount = 0;
    //一个导联是否脱落的状态 脱落为true
    private static boolean bodyLeadState = false;
    //导联首次全部连上  为true
    private static boolean bodyLeadState_GREEN = false;
    //导联全部连上，等于9时，表示首次连上，显示导联图
    private static int bodyLeadState_GREEN_First = 0;
    //循环播放导联脱落的音频ID
    private int playBodyLeadOffSound = -1;
    //播放开始测量音频的ID
    private int playStartEcgSound = -1;
    private int stepCount = 0;
    int[] baseY, baseX;

    int[] oldY = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    private SampleDotIntNew[] sampleDot;
    //蓝牙或者是串口采集服务是否还在运行
    private boolean DataServiceIsRunning = false;
    //24小时或者是手动的测量开始时间
    private long manualEcgStartTime = -1;
    //是否将测量的心电数据和时间返回给上一个页面
    protected boolean isReceiveEcgData;


    //该参数是用来对原始的心电数据转化为电压值的时候使用的
    private static int value = 10500;
    private boolean[] isFirstDrawWave = new boolean[]{false, false, false, false, false, false, false, false, false, false, false, false}; //是否首次绘制
    //理解为现在是几倍屏幕
    private int screenSize;
    private long bodyLeadStateStart = 0;
    private int callData_count = 0;

    private final int DRAW_ECG_WAVE = 1000;
    //经典蓝牙连接失败
    private final int BT_CONNECT_FAILED = 997;
    private final int BT_CONNECTED = 996;
    private final int USB_DETACHED = 995;
    private final int BLUETOOTH_DETACHED = 991;
    private final int HEART_NUM = 992;
    private final int BT_CONNECT_DEVICE_ERROR = 899;
    private final int BODY_LEAD_STATE_OFF = 898;
    private final int SAVE_PDF_XML_FILE_SUCCESS = 897;
    private final int SAVE_PDF_XML_TIMECOUNT = 896;


    private final int MANUAL_ECG_AUTO_FINISH_FLAG = 100010;
    //绘制导联之前的准备工作完成的通知
    private final int DRAW_BODY_LEAD_READ_STATE = 805;
    //纸速改变
    private final int SWITCH_SPEED_DRAW_WAVE = 804;
    private final int DRAW_BODY_LEAD_STATE = 803;
    private final int DRAW_BODY_LEAD_START = 802;
    private final int DISMISS_PROGRESS_DIALOG = 801;
    private final int SHOW_PROGRESS_DIALOG = 800;

    private final static int STATUS_START = 0;
    private final static int STATUS_STOP = 1;

    private int status = STATUS_START;

    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 10011:
                    ToastUtil.INSTANCE.toast((String) msg.obj);
                    break;
                //正确接受到串口或者是蓝牙的数据 准备开始绘制
                case DRAW_ECG_WAVE:
                    if (!isFinishing() && progressDialog != null) {
                        progressDialog.dismiss();
                    }
                    clearCache();
                    drawWaveTimeTask = new DrawWaveTimeTask();
                    drawTimer.schedule(drawWaveTimeTask, 4, 15);
                    isRestartDraw = true;
                    break;
                //蓝牙或者是串口连接失败
                case BT_CONNECT_FAILED:
                    if (!isFinishing() && progressDialog != null) {
                        progressDialog.dismiss();
                    }
                    String reason = (String) msg.obj;
                    ToastUtil.INSTANCE.toast(getResources().getString(R.string.prompt_connection_failed) + reason);
                    finish();
                    break;
                //串口连接成功
                case BT_CONNECTED:
                    //ble蓝牙连接成功
                case DISMISS_PROGRESS_DIALOG:
                    if (!isFinishing() && progressDialog != null) {
                        progressDialog.dismiss();
                    }
                    break;
                //显示心率
                case HEART_NUM://心率显示
                    int heart = (Integer) msg.obj;
                    if (heart > 0) {
                        dataBinding.ecgMeasureHeartBeat.setText(String.valueOf(heart));
                    } else if (heart < 0) {
                        dataBinding.ecgMeasureHeartBeat.setText("---");
                    }
                    break;
                //串口或者是蓝牙连接失败
                case BT_CONNECT_DEVICE_ERROR:
                    isDrawECGWave = false;
                    if (isFinishing()) {
                        return;
                    }
                    if (progressDialog != null) {
                        progressDialog.dismiss();
                    }
                    if (drawTimer != null) drawTimer.cancel();
                    noticeFinishDialog((String) msg.obj);
                    break;

                //保存完成文件后的处理
                case SAVE_PDF_XML_FILE_SUCCESS:
                    if (!isFinishing() && progressDialog != null) {
                        progressDialog.dismiss();
                    }
                    if (saveFileType == 2) {
                        if (saveManualMinuteCount == 1440) {//hour24State     saveFileManualCount == 1440
                            isDrawECGWave = true;
                            stopDataSource();
                            if (!isFinishing() && progressDialog != null && progressDialog.isShowing()) {
                                progressDialog.dismiss();
                            }
                            if (isReceiveEcgData) {
                                invokeFinish("");
                            } else {
                                twoFourFinish();
                                noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_24finished));
                            }
                            popDataBinding.ecgMeasurePopStart.setText(getResources().getString(R.string.ecg_measure_pop_start));
                            status = STATUS_START;
                        }
                    } else if (saveFileType == 1) {//手动模式
                        if (saveManualMinuteCount == 120) {//120分钟
                            stopDataSource();
                            manualEcgStartTime = -1;
                            if (!isFinishing() && progressDialog != null && progressDialog.isShowing()) {
                                progressDialog.dismiss();
                            }
                            if (isReceiveEcgData) {
                                invokeFinish("");
                            } else {
                                noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_2finished));
                                manualFinish();
                            }
                        } else if (status == STATUS_STOP) {
                            noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_done_savingdata));
                        }
                        popDataBinding.ecgMeasurePopStart.setText(getResources().getString(R.string.ecg_measure_pop_start));
                        status = STATUS_START;

                    } else if (saveFileType == 0) {
                        String filePath = (String) msg.obj;
                        if (isReceiveEcgData) {
                            invokeFinish(filePath);
                        } else {
                            Intent intent = new Intent("com.wehealth.ecg.report.activity");
                            intent.putExtra("filename", filePath);
                            startActivity(intent);
                            finish();
                        }
                    }
                    break;
                //测量心电时的计时显示
                case SAVE_PDF_XML_TIMECOUNT:
                    if (saveFileType == 0) {
                        dataBinding.ecgMeasureStartTime.setText(timeSecondCount + "秒");
                    } else {
                        if (timeSecondCount == 60) {
                            timeMinuteCount++;
                        }
                        if (timeMinuteCount == 60) {
                            timeMinuteCount = 0;
                            timeHourCount++;
                        }
                        dataBinding.ecgMeasureStartTime.setText(timeHourCount + "时" + timeMinuteCount + "分" + (timeSecondCount % 60) + "秒");
                    }
                    break;
                case SHOW_PROGRESS_DIALOG:
                    if (!isFinishing() && progressDialog != null) {
                        String dialog_message = (String) msg.obj;
                        progressDialog.setMessage(dialog_message);
                        if (!progressDialog.isShowing()) {
                            progressDialog.show();
                        }
                    }
                    break;
                case DRAW_BODY_LEAD_STATE://导联连接成功后， 延时两秒钟
                    long end = System.currentTimeMillis();
                    if (end - bodyLeadStateStart >= 1800) {//是延时两秒钟
                        initAnalyse();
                        baseLineState = -1;
                        isDrawECGWave = false;
                        bodyLeadState_GREEN = false;
                        isRestartDraw = true;
                        clearCache();
                        setButtonEnabled(true);
                        if (saveFileType == 2) {
                            popDataBinding.ecgMeasurePopDisplay.setEnabled(false);
                        }
                        if (saveFileType == 2 || waveDisplayType == 2) {
                            dataBinding.measureEcgDisplayChange.setVisibility(View.VISIBLE);
                        }
                    }
                    break;
                case DRAW_BODY_LEAD_START://导联连接成功，开始测量心电
                    if (playBodyLeadOffSound != -1) {
                        soundPool.stop(playBodyLeadOffSound);
                        playBodyLeadOffSound = -1;
                    }
                    if (playStartEcgSound != -1) {
                        soundPool.stop(playStartEcgSound);
                    }
                    playStartEcgSound = soundPool.play(soundPoolId[2], 1.0F, 1.0F, 1, 0, 1.0F);

                    break;
                case BODY_LEAD_STATE_OFF://导联脱落时播放音频  绘制导联脱落的画面
                    dataBinding.ecgMeasureStartTime.setText("");
                    if (saveFileType == 1) {
                        popDataBinding.ecgMeasurePopStart.setText(getResources().getString(R.string.ecg_measure_pop_start));
                        status = STATUS_START;
                    }
                    if (saveFileType == 2) {
                        setButtonEnabled(true);
                    }
                    dataBinding.measureEcgDisplayChange.setVisibility(View.INVISIBLE);
                    if (playStartEcgSound != -1) {
                        soundPool.stop(playStartEcgSound);
                        playStartEcgSound = -1;
                    }
                    if (playBodyLeadOffSound != -1) {
                        soundPool.stop(playBodyLeadOffSound);
                    }

                    playBodyLeadOffSound = soundPool.play(soundPoolId[1], 1.0F, 1.0F, 1, -1, 1.0F);
                    break;
                case SWITCH_SPEED_DRAW_WAVE://切换纸速
                    if (!isFinishing() && progressDialog != null) {
                        progressDialog.dismiss();
                    }
                    dataBinding.ecgMeasureSpeed.setEnabled(true);
                    isDrawECGWave = false;
                    break;
                case DRAW_BODY_LEAD_READ_STATE:
                    //绘制导联检测之前的黑色页面和姿势提示图片
                    drawBodyLeadReadState();
                    break;
                case USB_DETACHED://USB连接断开
                    if (playBodyLeadOffSound != -1) {
                        soundPool.stop(playBodyLeadOffSound);
                    }
                    stopDataSource();
                    if (!isFinishing()) {
                        noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_usb_broken));
                    }
                    break;
                case BLUETOOTH_DETACHED:
                    if (playBodyLeadOffSound != -1) {
                        soundPool.stop(playBodyLeadOffSound);
                    }
                    stopDataSource();
                    if (!isFinishing()) {
                        noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_bt_broken));
                    }
                    break;

                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        dataBinding = DataBindingUtil.setContentView(this, R.layout.surface_measure);
        popDataBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.layout_ecg_measure_pop, null, false);
        initView();
        receiveOtherApp();
        initSoundResource();
        initData();
    }


    /***
     * 当前方法处理上层应用传递的参数
     */
    private void receiveOtherApp() {
        Intent intent = getIntent();
        if (intent != null) {
            patientId = intent.getStringExtra(ConstantKey.PATIENT_USER_ID);
            patientAge = intent.getIntExtra(ConstantKey.PATIENT_USER_AGE, 60);
            patientName = intent.getStringExtra(ConstantKey.PATIENT_USER_NAME);
            patientGender = intent.getIntExtra(ConstantKey.PATIENT_USER_GENDER, 0);
            waveGain = intent.getIntExtra(ConstantKey.USER_WAVE_GAIN, 4);
            waveSpeed = intent.getIntExtra(ConstantKey.USER_WAVE_SPEED, 0);
            waveDisplayType = intent.getIntExtra(ConstantKey.USER_WAVE_DISPLAY, 0);
            waveIsPace = intent.getBooleanExtra(ConstantKey.USER_WAVE_PACE, false);
            searchType = intent.getIntExtra(USER_ECG_SEARCH_TYPE, 1);
            saveFileType = intent.getIntExtra(ConstantKey.USER_ECG_FILE_SAVE_TYPE, 0);
            appConnectType = intent.getIntExtra(ConstantKey.USER_ECG_CONNECT_TYPE, 1);
            if (saveFileType == 2) {
                waveDisplayType = 2;
            } else {
                waveDisplayType = 0;
            }
            if (intent.hasExtra(USER_ECG_IS_RESULT)) {
                //测量结果的数据如何处理
                isReceiveEcgData = intent.getBooleanExtra(USER_ECG_IS_RESULT, false);
            }
        }
    }


    /***
     * 加载音频使用的资源
     */
    private void initSoundResource() {
        //音频数据
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            soundPool = new SoundPool.Builder().setMaxStreams(12).build();
        } else {
            soundPool = new SoundPool(12, 3, 0);
        }
        try {
            String heartBeepFile = getResources().getString(R.string.audio_heart_beep);
            soundPoolId[0] = soundPool.load(getResources().getAssets().openFd(heartBeepFile), 1);
            String leadOffFile = getResources().getString(R.string.audio_leadoff);
            soundPoolId[1] = soundPool.load(getResources().getAssets().openFd(leadOffFile), 1);
            String startAdFile = getResources().getString(R.string.audio_start_ad);
            soundPoolId[2] = soundPool.load(getResources().getAssets().openFd(startAdFile), 1);
            String stopAdFile = getResources().getString(R.string.audio_stop_ad);
            soundPoolId[3] = soundPool.load(getResources().getAssets().openFd(stopAdFile), 1);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    /***
     * 初始化布局的view此处主要是处理的popWindow弹出的准备工作
     */
    private void initView() {

        measureActivity = this;
        //获取当前的屏幕的可用高度
        screenSize = getResources().getDisplayMetrics().heightPixels <= 800 ? 1 : 2;
        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        //悬浮的配置信息view
        popDataBinding.getRoot().measure(w, h);
        //测量页面左下角的按钮的布局参数
        dataBinding.ecgMeasurePopContainer.measure(w, h);
        //获取当前view的布局之后的宽度
        int width = popDataBinding.getRoot().getMeasuredWidth();
        dataBinding.ecgMeasurePopContainer.post(() -> {
            int height = dataBinding.ecgMeasurePopContainer.getMeasuredHeight();
            //点击左下角按钮之后弹出一个自定义样式的view
            pop = new PopupWindow(popDataBinding.getRoot(), width, height);
        });
        dataBinding.measureEcgDisplayChange.setOnClickListener(this);
        dataBinding.ecgMeasurePopContainer.setOnClickListener(this);
        popDataBinding.ecgMeasurePopSpeed.setOnClickListener(this);
        popDataBinding.ecgMeasurePopGain.setOnClickListener(this);
        popDataBinding.ecgMeasurePopFilterOne.setOnClickListener(this);
        popDataBinding.ecgMeasurePopDisplay.setOnClickListener(this);
        popDataBinding.ecgMeasurePopStart.setOnClickListener(this);
        popDataBinding.ecgMeasurePopOpen.setOnClickListener(this);
        popDataBinding.ecgMeasurePopSound.setOnClickListener(this);
    }

    public void initData() {
        saveFileAutoThread = new SaveFileAutoThread(handler);
        //12个导测量的绘制的y坐标
        baseY = new int[LEAD_NUM];
        //开始绘制的x坐标
        currentX = 30;
        //12个导测量的绘制的x坐标
        baseX = new int[LEAD_NUM];
        //初始化画板
        initCanvas();
        initSampleDot();
        //初始化存储数据相关的参数
        initSaveData();
        //获取心率的对象
        hrDetect = new EcgHRDetect();
        //心电数据滤波对象
        ecgFilter = new EcgFilter();
        //心电数据进行滤波的时候需要的参数
        FilterBase = 4;
        FilterMC = 12;
        FilterLP = 36;
        FilterAC = 22;
        //动态库对心电数据处理的初始化
        initAnalyse();
        //定时器
        drawTimer = new Timer();
        progressDialog = new ProgressDialog(this);
        loadingDialog = new LoadingDialog(getResources().getString(R.string.prompt_searching_bt_devices), getSupportFragmentManager());
        finishScanBlueToothTask = new FinishScanBlueToothTask();
        finishScanTimer.schedule(finishScanBlueToothTask, 1000 * 10);
        WindowManager.LayoutParams params = progressDialog.getWindow().getAttributes();
        progressDialog.getWindow().setGravity(Gravity.TOP);
        params.y = 60;
        progressDialog.getWindow().setAttributes(params);
        progressDialog.setCancelable(false);
        setButtonEnabled(false);
        //测量时间
        dataBinding.ecgMeasureStartTime.setVisibility(View.VISIBLE);
        //获取蓝牙通用功能检测对象
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null) {
            ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_bt_not_supported));
            return;
        }
        //获取usb通用功能检测对象
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        connectDevice();
        DataServiceIsRunning = true;
    }

    /****
     * 连接测心电的设备
     */
    private void connectDevice() {
        if (appConnectType == 1) {
            connectUsbDevice();
        } else if (appConnectType == 2) {
            connectBlueToothDevice();
        } else {

            ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_waiting));
        }
    }


    /***
     * 连接usb设备
     */
    private void connectUsbDevice() {
        MainHandler.INSTANCE.postDelay(1000L, () -> {
            HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
            if (deviceList.size() == 0) {
                ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_usb_first) + deviceList.size());
                return;
            }
            Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
            if (deviceList.size() == 1) {
                UsbDevice device = deviceIterator.next();
                //是否已经包含和usb通信使用的权限
                if (usbManager.hasPermission(device)) {
                    int vendorId = device.getVendorId();
                    int productId = device.getProductId();
                    //二代机的usb设备
                    if (vendorId == 4292 || productId == 60001 || productId == 60000) {
                        ToastUtil.INSTANCE.toast("2");
                        usbType = 2;
                        connectUsb(usbType);
                    } else if (vendorId == 1155 && productId == 22336) {
                        ToastUtil.INSTANCE.toast("3");
                        usbType = 3;
                        connectUsb(usbType);
                    } else {
                        ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_usb_not_supported));
                    }
                } else {
                    //通过对话框提示申请权限
                    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
                    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
                    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
                    registerReceiver(mUsbReceiver, filter);
                    @SuppressLint("UnspecifiedImmutableFlag")
                    PendingIntent mPermissionIntent = PendingIntent.getBroadcast(ECGMeasureActivity.this, 0, new Intent(ACTION_USB_PERMISSION), 0);
                    usbManager.requestPermission(device, mPermissionIntent);
                }
            }
        });

    }


    /***
     * 连接蓝牙设备
     */
    private void connectBlueToothDevice() {
        if (isFinishing()) return;
        if (!bluetoothAdapter.isEnabled()) {
            noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_open_bt_first));
            return;
        }
        if (new ClassicBlueUtils().socketIsConn()) {
            connectStreamThread = new BTConnectStreamThread(null, 2, handler, ECGMeasureActivity.this);
            connectStreamThread.start();
            DataServiceIsRunning = true;
            return;
        }
        String btMac = PreferenceUtils.getInstance().getECGDeviceBTMAC(PreferenceUtils.getInstance().getIdCardNo());
        //是否是经典蓝牙优先搜索
        boolean btType = PreferenceUtils.getInstance().getDeviceBluetoothType();
        //经典蓝牙的mac地址已保存的状态
        if (btMac != "") {
            if (btType) {
                connectClassicBlueTooth(btMac, 0);
            } else {
                connectBleBlueTooth(btMac);
            }
        } else {
            if (isFinishing()) return;
            //无mac地址需要搜索
            loadingDialog.openDialog();
            scanCommonBlueDevice();
        }
    }

    /****
     * 蓝牙无本地缓存通过扫描连接蓝牙
     */
    @SuppressLint("MissingPermission")
    private void scanCommonBlueDevice() {
        BleBoothToothHelper bleBoothToothHelper = new BleBoothToothHelper(this);
        ClassicBlueToothHelper classicBlueToothHelper = new ClassicBlueToothHelper(this);
        classicBlueToothHelper.isEnableBT(() -> {
                    ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_open_bt));
                    return null;
                }
        );
        classicBlueToothHelper.isSupportBT(() -> {
            ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_bt_not_supported));
            return null;
        });
        progressDialog.dismiss();
        //是否是经典蓝牙
        boolean btType = PreferenceUtils.getInstance().getDeviceBluetoothType();
        //是否两种模式均搜索
        if (searchType == 0) {
            ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_bt_search_both));
            // 是经典蓝牙 先搜经典 后ble
            if (btType) {
                classicBlueToothHelper.discoverDevice();
                MainHandler.INSTANCE.postDelay(5000, () -> {
                    classicBlueToothHelper.stopDiscoverDevice();
                    bleBoothToothHelper.discoverDevice();
                    MainHandler.INSTANCE.postDelay(5000, () -> bleBoothToothHelper.stopDiscoverDevice());
                });
            } else {
                //BLE 先搜ble后经典
                bleBoothToothHelper.discoverDevice();
                MainHandler.INSTANCE.postDelay(5000, () -> {
                    classicBlueToothHelper.discoverDevice();
                    MainHandler.INSTANCE.postDelay(5000, () -> classicBlueToothHelper.stopDiscoverDevice());
                });
            }
            MainHandler.INSTANCE.postDelay(10000, () -> {
                List<BluetoothDevice> deviceList = new ArrayList<>();
                deviceList.addAll(classicBlueToothHelper.getDeviceList());
                deviceList.addAll(bleBoothToothHelper.getBleDeviceList());
                loadingDialog.closeDialog();
                if (deviceList.size() > 1) {
                    BlueToothDeviceListDialog deviceListDialog = new BlueToothDeviceListDialog(deviceList, () -> {
                        connectBlueToothDevice();
                        return null;
                    }, bluetoothDevice -> {
                        connectClassicBlueTooth(bluetoothDevice.getAddress(), 1);
                        return null;
                    });
                    deviceListDialog.show(getSupportFragmentManager(), "ssss");

                } else if (deviceList.size() == 1) {
                    progressDialog.show();
                    // 1 classic 2 ble
                    if (deviceList.get(0).getType() == 1) {
                        connectClassicBlueTooth(deviceList.get(0).getAddress(), 1);
                    } else {
                        connectBleBlueTooth(deviceList.get(0).getAddress());
                    }
                } else {
                    loadingDialog.dismiss();
                    noticeDialog(getResources().getString(R.string.prompt_not_found_device), () -> {
                        connectBlueToothDevice();
                        return null;
                    });

                }
            });
            //只单独搜索一种
        } else {
            ToastUtil.INSTANCE.toast("classic");
            //  只搜索经典 5s自动结束
            if (searchType == 1) {
                scanClassicDevice(classicBlueToothHelper);
            } else if (searchType == 2) {
                ToastUtil.INSTANCE.toast("ble");
                scanBleDevice(bleBoothToothHelper);
            }
        }
    }

    /***
     * 只搜索经典蓝牙的设备
     * @param classicBlueToothHelper
     */
    private void scanClassicDevice(ClassicBlueToothHelper classicBlueToothHelper) {
        classicBlueToothHelper.discoverDevice();
        MainHandler.INSTANCE.postDelay(5000, () ->
                {
                    classicBlueToothHelper.stopDiscoverDevice();
                    if (classicBlueToothHelper.getDeviceList().size() > 1) {
                        //对话框处理
                    } else if (classicBlueToothHelper.getDeviceList().size() == 1) {
                        connectClassicBlueTooth(classicBlueToothHelper.getDeviceList().get(0).getAddress(), 1);
                    } else {
                        loadingDialog.dismiss();
                        noticeDialog(getResources().getString(R.string.prompt_not_found_device), () -> {
                            connectBlueToothDevice();
                            return null;
                        });
                    }
                }
        );
    }

    /***
     * 只搜索ble蓝牙的设备
     * @param bleBoothToothHelper
     */
    private void scanBleDevice(BleBoothToothHelper bleBoothToothHelper) {
        //只搜索ble 5s后自动结束
        bleBoothToothHelper.discoverDevice();
        MainHandler.INSTANCE.postDelay(100000, () -> {
            if (bleBoothToothHelper.getBleDeviceList().size() > 1) {
                //对话框处理
            } else if (bleBoothToothHelper.getBleDeviceList().size() == 1) {
                connectBleBlueTooth(bleBoothToothHelper.getBleDeviceList().get(0).getAddress());
            } else {
                loadingDialog.dismiss();
                noticeDialog(getResources().getString(R.string.prompt_not_found_device), () -> {
                    connectBlueToothDevice();
                    return null;
                });
            }
        });
    }

    /***
     * 连接经典蓝牙设备
     * @param macAddress
     */
    @SuppressLint("MissingPermission")
    private void connectClassicBlueTooth(String macAddress, int type) {
        BluetoothDevice currentDevice = bluetoothAdapter.getRemoteDevice(macAddress);
        progressDialog.setMessage(getResources().getString(R.string.prompt_connecting));
        progressDialog.show();
        connectStreamThread = new BTConnectStreamThread(currentDevice, type, handler, ECGMeasureActivity.this);
        connectStreamThread.start();
        DataServiceIsRunning = true;
    }

    /***
     * 连接ble蓝牙
     * @param macAddress
     */
    private void connectBleBlueTooth(String macAddress) {
        BluetoothDevice currentDevice = bluetoothAdapter.getRemoteDevice(macAddress);
        bleConnThread = new BleConnectThread(this, currentDevice, handler, this);
        bleConnThread.start();
    }

    /***
     * 二代机的usb设备的连接
     */
    private void connectUsb(int usbType) {
        List<UsbSerialDriver> listUSDs = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
        UsbSerialDriver usbSerialDriver = listUSDs.get(0);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < listUSDs.size(); i++) {
            stringBuilder.append(listUSDs.get(i).getDevice().getVendorId());
            stringBuilder.append(listUSDs.size());
            stringBuilder.append("\n");
        }

        SaveLogUtil.writLog2File("test.txt", stringBuilder.toString());

        if (usbSerialDriver == null) {
            connectBlueToothDevice();
            return;
        }
        UsbDeviceConnection usbConnection = usbManager.openDevice(usbSerialDriver.getDevice());
        if (usbConnection == null) {
            connectBlueToothDevice();
            return;
        }
        UsbSerialPort usbSerialPort = usbSerialDriver.getPorts().get(0);
        if (usbSerialPort == null) {
            connectBlueToothDevice();
            return;
        }
        usbSerialThread = new UsbSerialThread(usbType, usbConnection, usbSerialPort, handler, this);
        usbSerialThread.start();
    }

    /****
     * 申请usb权限
     */
    private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            SaveLogUtil.writLog2File("text.txt", action);
            if (ACTION_USB_PERMISSION.equals(action)) {
                SaveLogUtil.writLog2File("text.txt", intent.getBooleanExtra("permission", false) + "");
                if (intent.getBooleanExtra("permission", false)) {
                    UsbDevice device = intent.getParcelableExtra("device");
                    int vendorId = device.getVendorId();
                    int productId = device.getProductId();
                    if (vendorId == 4292 || productId == 60001 || productId == 60000) {
                        usbType = 2;
                        connectUsb(usbType);
                    } else if (vendorId == 1155 && productId == 22336) {
                        usbType = 3;
                        connectUsb(usbType);
                    } else {
                        connectBlueToothDevice();
                    }
                } else {
                    finish();
                }
            }
        }
    };

    private void initAnalyse() {
        hrDetect.initHr(3495.2533333f * 3);
        ecgFilter.initFilter(FilterBase, FilterMC, FilterAC, FilterLP);
        ecgFilter.initBaseLineJudge();
    }

    private void initCanvas() {
        //姿势提示人物图片的宽度
        bodyImgW = 290;
        //姿势提示人物图片的高度
        bodyImgH = 264;
        //进行心电图绘制的view的绘制区域的获取
        surfaceHolder = dataBinding.measureEcgSurface.getHolder();
        /* 绘制前获取控件尺寸 */
        dataBinding.measureEcgSurface.post(() -> {
            //获取surfaceView的宽度
            screenWidth = dataBinding.measureEcgSurface.getMeasuredWidth();
            //获取surfaceView的高度
            screenHeight = dataBinding.measureEcgSurface.getMeasuredHeight();
            //通过姿势提示人物和屏幕的高度的比例计算宽度
            percentH = screenHeight / bodyImgH;
            bodyPercentW = percentH * bodyImgW;
            //屏幕绘制了姿势提示人物的剩余空间
            side = screenWidth - bodyPercentW;
            //绘制是个导联状态的点
            for (int i = 0; i < 10; i++) {
                leadX[i] = (leadX[i] - 136) * percentH + side / 2;
                leadY[i] = leadY[i] * percentH;
            }
            //获取首次绘制的背景图片
            backMap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
            //获取绘制心电图的背景图片
            waveMap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
            //导联姿势提示人物图片
            bodyLeadMap = BitmapFactory.decodeResource(getResources(), R.drawable.body_bg);
            //创建绘制心电图的画板
            waveCanvas = new Canvas(waveMap);
            waveCanvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
            handler.sendEmptyMessageDelayed(DRAW_BODY_LEAD_READ_STATE, 200);
        });
        //使用的一些画笔的初始化
        mPaint = new Paint();
        greenPaint = new Paint();
        greenPaint.setColor(Color.GREEN);
        redPaint = new Paint();
        redPaint.setColor(Color.RED);
        mPaint.setColor(Color.GREEN);
        greyPaint = new Paint();
        greyPaint.setColor(getResources().getColor(R.color.color_666666));
        greyPaint.setStrokeWidth(1);
        mPaint.setAntiAlias(true);
        pacePaint = new Paint();
        pacePaint.setStrokeWidth(1.5f);
        pacePaint.setColor(Color.RED);
        subGridPaint = new Paint();
        topGridPaint = new Paint();
        topGridPaint.setColor(getResources().getColor(R.color.ecg_line_cu));
        topGridPaint.setStrokeWidth((float) 1.5);
        subGridPaint.setColor(getResources().getColor(R.color.ecg_line_xi));
    }


    @Override
    public void onClick(View v) {
        //显示设置弹窗
        if (v.getId() == R.id.ecg_measure_pop_container) {
            //设置popWindow内部的按钮状态为可用
            setButtonEnabled(true);
            //弹出配置的弹窗
            showTestPopWin();
        }
        //关闭设置弹窗
        if (v.getId() == R.id.ecg_measure_pop_open) {
            if (pop != null && pop.isShowing()) pop.dismiss();
        }
        //切换心电图的绘制模式
        if (v.getId() == R.id.ecg_measure_pop_display) {//显示按钮
            if (drawWaveTimeTask != null) {
                drawWaveTimeTask.cancel();
            }
            pop.dismiss();
            currentX = 30;
            Message msg = handler.obtainMessage(SHOW_PROGRESS_DIALOG);
            msg.obj = getResources().getString(R.string.activity_ecgmeasure_switching);
            handler.sendMessage(msg);
            waveDisplayType = (waveDisplayType + 1) % 3;
            handler.sendEmptyMessageDelayed(DRAW_ECG_WAVE, 800);
            //只有在显示一个导联的时候切换按钮才可用
            if (waveDisplayType == 2) {
                dataBinding.measureEcgDisplayChange.setVisibility(View.VISIBLE);
            } else {
                dataBinding.measureEcgDisplayChange.setVisibility(View.GONE);
            }
            isFirstDrawWave = new boolean[]{false, false, false, false, false, false, false, false, false, false, false, false};
        }

        if (v.getId() == R.id.ecg_measure_pop_filter_one) {//滤波按钮
            isDrawECGWave = true;
            if (saveFileType == 0) {
                isSaveFile = false;
            }
            if (saveFileType == 1 && status == STATUS_STOP) {
                isSaveFile = false;
            }
            pop.dismiss();
            showFilterDialog();
        }
        if (v.getId() == R.id.ecg_measure_pop_gain) {//增益按钮
            pop.dismiss();
            waveGainChange();
        }
        if (v.getId() == R.id.ecg_measure_pop_sound) {//声音按钮
            pop.dismiss();
            isPlaySound = !isPlaySound;
        }
        if (v.getId() == R.id.ecg_measure_pop_speed) {//纸速按钮
            pop.dismiss();
            waveSpeedChange();
        }
        if (v.getId() == R.id.ecg_measure_pop_start) {//开始采集按钮
            if (saveFileType == 2) {//24小时
                pop.dismiss();
                if (status == STATUS_START) {
                    twoFourStart();
                } else if (status == STATUS_STOP) {
                    twoFourFinish();
                }
            } else if (saveFileType == 1) {//手动模式
                pop.dismiss();
                if (status == STATUS_START) {
                    manualStart();
                } else if (status == STATUS_STOP) {
                    manualFinish();
                }
            } else if (saveFileType == 0) {//自动模式
                pop.dismiss();
                saveFileSecondCount = 5000;
                saveCount = 0;
                currentX = 30;
                baseLineState = 0;
                bufferAuto.clear();
                isSaveFile = true;
                popDataBinding.ecgMeasurePopStart.setEnabled(true);
            }
        }


        //只有单导显示的时候才能切换显示
        if (v.getId() == R.id.measure_ecg_display_change) {
            if (waveDisplayType == 2) {
                waveSingleDisplaySwitch = (waveSingleDisplaySwitch + 1) % 12;
            }
        }
    }


    private void twoFourStart() {
        isSaveFile = true;
        saveFileSecondCount = 60 * 500;
        saveCount = 0;
        baseLineState = 0;
        buffer24H.clear();
        setButtonEnabled(false);
        popDataBinding.ecgMeasurePopStart.setEnabled(true);
        dataBinding.measureEcgDisplayChange.setEnabled(false);
        manualEcgStartTime = System.currentTimeMillis();
        saveFile24HThread = new SaveFile24HThread(handler, manualEcgStartTime);
        saveFile24HThread.start();
        popDataBinding.ecgMeasurePopStart.setText(getResources().getString(R.string.ecg_measure_pop_stop));
        status = STATUS_STOP;
    }


    private void twoFourFinish() {
        if (saveManualMinuteCount > 0) {
            saveFile24HThread.setThreadFlag(false);
            if (status == STATUS_STOP) {
                stopDataSource();
                noticeFinishDialog(getResources().getString(R.string.activity_ecgmeasure_24hour_data_saved));
                popDataBinding.ecgMeasurePopStart.setText(getResources().getString(R.string.ecg_measure_pop_start));
                status = STATUS_START;
            }

        } else {
            ToastUtil.INSTANCE.toast(getResources().getString(R.string.activity_ecgmeasure_24hour_prompt_morethan_1m));
        }

    }

    /***
     * 自动测量开始采集
     */
    private void manualStart() {
        saveFileSecondCount = 60 * 500;
        saveCount = 0;
        isSaveFile = true;
        baseLineState = 0;
        initManualBuffer();
        manualEcgStartTime = System.currentTimeMillis();
        if (saveFileManualThread != null) {
            saveFileManualThread.setThreadFlag(false);
            saveFileManualThread = null;
        }
        saveFileManualThread = new SaveFileManualThread(this, handler);
        saveFileManualThread.start();
        popDataBinding.ecgMeasurePopStart.setText(getResources().getString(R.string.ecg_measure_pop_stop));
        status = STATUS_STOP;
    }

    /***
     * 自动测量结束采集
     */
    private void manualFinish() {
        dataBinding.ecgMeasureStartTime.setText("");
        isSaveFile = false;
        isDrawECGWave = true;
        if (!isFinishing() && progressDialog != null) {
            progressDialog.setMessage(getResources().getString(R.string.activity_ecgmeasure_prompt_analysis));
            progressDialog.show();
        }
        Integer[] d0 = new Integer[buf0.size()];
        buf0.toArray(d0);
        Integer[] d1 = new Integer[buf1.size()];
        buf1.toArray(d1);
        Integer[] d2 = new Integer[buf2.size()];
        buf2.toArray(d2);
        Integer[] d3 = new Integer[buf3.size()];
        buf3.toArray(d3);
        Integer[] d4 = new Integer[buf4.size()];
        buf4.toArray(d4);
        Integer[] d5 = new Integer[buf5.size()];
        buf5.toArray(d5);
        Integer[] d6 = new Integer[buf6.size()];
        buf6.toArray(d6);
        Integer[] d7 = new Integer[buf7.size()];
        buf7.toArray(d7);
        Integer[] d8 = new Integer[buf8.size()];
        buf8.toArray(d8);
        Integer[] d9 = new Integer[buf9.size()];
        buf9.toArray(d9);
        Integer[] d10 = new Integer[buf10.size()];
        buf10.toArray(d10);
        Integer[] d11 = new Integer[buf11.size()];
        buf11.toArray(d11);
        Map<String, Object> map = new HashMap<>();
        map.put("FilterBase", dataBinding.ecgMeasureFilterTwo.getText().toString());
        map.put("FilterMC", dataBinding.ecgMeasureFilterThree.getText().toString());
        map.put("FilterAC", dataBinding.ecgMeasureFilterOne.getText().toString());
        map.put("FilterLP", dataBinding.ecgMeasureFilterFour.getText().toString());
        map.put("HeartRate", dataBinding.ecgMeasureHeartBeat.getText().toString());
        map.put("waveGain", waveGain);
        map.put("waveSpeed", waveSpeed);
        map.put("waveSingleDisplay_Switch", waveSingleDisplaySwitch);
        map.put("ecg2DeviceData_time", manualEcgStartTime);
        map.put("PAT_ID", patientId);
        map.put("PAT_AGE", patientAge);
        map.put("PAT_GENDER", patientGender);
        map.put("PAT_NAME", patientName);
        map.put("ecgDataBuffer0", d0);
        map.put("ecgDataBuffer1", d1);
        map.put("ecgDataBuffer2", d2);
        map.put("ecgDataBuffer3", d3);
        map.put("ecgDataBuffer4", d4);
        map.put("ecgDataBuffer5", d5);
        map.put("ecgDataBuffer6", d6);
        map.put("ecgDataBuffer7", d7);
        map.put("ecgDataBuffer8", d8);
        map.put("ecgDataBuffer9", d9);
        map.put("ecgDataBuffer10", d10);
        map.put("ecgDataBuffer11", d11);
        map.put("saveFileManualCount", saveManualMinuteCount);
        map.put("timeSecondCount", timeSecondCount);
        saveFileManualThread.addToQueue(map);
        stopDataSource();

    }

    /**
     * 初始化弹框
     **/
    private void showTestPopWin() {
        //获取点击View的坐标
        int[] location = new int[2];
        dataBinding.ecgMeasurePopContainer.getLocationOnScreen(location);
        pop.setFocusable(true);
        pop.setBackgroundDrawable(new ColorDrawable(0x00000000));
        pop.setAnimationStyle(R.style.mypopwindow_anim_style);
        pop.setOnDismissListener(() -> {
            pop.dismiss();
            dataBinding.ecgMeasurePopContainer.setVisibility(View.VISIBLE);
        });
        pop.showAtLocation(dataBinding.ecgMeasurePopContainer, Gravity.NO_GRAVITY, location[0], location[1]);//+ popLyt.getWidth()/2
    }

    /**
     * 给设备发送停止命令
     **/
    private void stopDataSource() {
        if (connectStreamThread != null) {
            connectStreamThread.stopBlueTooth();
        }
        if (drawWaveTimeTask != null) {
            drawWaveTimeTask.cancel();
        }

        if (usbSerialThread != null) {
            usbSerialThread.stopSerial();
            writeContentToFile(adb_command_dir, adb_command_typec.toCharArray());
        }
        bodyLeadState_GREEN_First = 0;
    }

    private void setButtonEnabled(boolean b) {
        popDataBinding.ecgMeasurePopStart.setEnabled(b);
        dataBinding.ecgMeasureSpeed.setEnabled(b);
        popDataBinding.ecgMeasurePopGain.setEnabled(b);
        dataBinding.ecgMeasureSpeed.setEnabled(b);
        popDataBinding.ecgMeasurePopFilterOne.setEnabled(b);
        popDataBinding.ecgMeasurePopDisplay.setEnabled(b);
        popDataBinding.ecgMeasurePopSound.setEnabled(b);
    }

    /****
     * 增益改变
     */
    private void waveGainChange() {
        waveGain *= 2;
        if (waveGain > 4) waveGain = 1;
        if (waveGain == 1) {
            dataBinding.ecgMeasureGain.setText("20");
        } else if (waveGain == 2) {
            dataBinding.ecgMeasureGain.setText("10");
        } else {
            dataBinding.ecgMeasureGain.setText("5");
        }
        waveGainChangeFlag = true;
    }

    /***
     * 纸速改变
     */
    @SuppressLint("SetTextI18n")
    private void waveSpeedChange() {
        Message msg = handler.obtainMessage(SHOW_PROGRESS_DIALOG);
        dataBinding.ecgMeasureSpeed.setEnabled(false);
        msg.obj = getResources().getString(R.string.activity_ecgmeasure_switching);
        handler.sendMessage(msg);
        isDrawECGWave = true;
        waveSpeed = (waveSpeed + 1) % 3;
        int ws = 125;
        if (screenSize == 1) {
            ws = 125;
        } else if (screenSize == 2) {
            ws = 248;
        }
        if (waveSpeed == 0) {
            dataBinding.ecgMeasureSpeed.setText("25");
        } else if (waveSpeed == 1) {
            dataBinding.ecgMeasureSpeed.setText("12.5");
            ws /= 2;
        } else {
            dataBinding.ecgMeasureSpeed.setText("50");
            ws *= 2;
        }
        initDeSampleDot(ws);//126 / (waveSpeed + 1)
        handler.sendEmptyMessageDelayed(SWITCH_SPEED_DRAW_WAVE, 1000);
    }


    /**
     * 具体绘制心电图的开始的地方
     **/
    private void SimpleDraw(List<int[]> datas) {
        DrawEcgWave(datas);
        currentX += stepCount;
        if (waveDisplayType == 0) {
            if (currentX >= (screenWidth / 2)) {
                currentX = 30;
            }
        } else {
            if (currentX >= screenWidth) {
                currentX = 30;
            }
        }
    }

    /**
     * 画波形图
     **/
    private void DrawEcgWave(List<int[]> datas) {
        List<int[]> leaData = StringUtils.getEcgData(datas);
        int lockStep = 0;
        if (waveDisplayType == 2) {
            dot13 = sampleDot[12].SnapshotSample(leaData.get(waveSingleDisplaySwitch));
            if (dot13 == null || dot13.isEmpty()) {
                stepCount = 0;
                return;
            }
            //这里理解为是水平方向绘制多少次？
            lockStep = dot13.size();
        } else {
            dot0 = sampleDot[0].SnapshotSample(leaData.get(0));//
            dot1 = sampleDot[1].SnapshotSample(leaData.get(1));//
            dot2 = sampleDot[2].SnapshotSample(leaData.get(2));//
            dot3 = sampleDot[3].SnapshotSample(leaData.get(3));//
            dot4 = sampleDot[4].SnapshotSample(leaData.get(4));//
            dot5 = sampleDot[5].SnapshotSample(leaData.get(5));//
            dot6 = sampleDot[6].SnapshotSample(leaData.get(6));//
            dot7 = sampleDot[7].SnapshotSample(leaData.get(7));//
            dot8 = sampleDot[8].SnapshotSample(leaData.get(8));//
            dot9 = sampleDot[9].SnapshotSample(leaData.get(9));//
            dot10 = sampleDot[10].SnapshotSample(leaData.get(10));//
            dot11 = sampleDot[11].SnapshotSample(leaData.get(11));//
            if (dot0 == null || dot0.isEmpty()) {
                stepCount = 0;
                return;
            }
            lockStep = dot0.size();
        }

        stepCount = lockStep;
        //这里就是初始换一个绘制区域画板waveCanvsa的大小
        if (stepCount > 0) {
            Rect rect = new Rect();
            if (currentX == 30) {
                //绘制完第一屏幕心电图之后
                rect.set(currentX, 0, currentX + SCREEN_MARGIN + stepCount + 6 * SCREEN_MARGIN, screenHeight);
            } else {
                //绘制第一个屏幕心电图
                rect.set(currentX + SCREEN_MARGIN, 0, currentX + SCREEN_MARGIN + stepCount + 5 * SCREEN_MARGIN, screenHeight);
            }
            waveCanvas.drawBitmap(backMap, rect, rect, null);
            if (waveDisplayType == 0) {
                if (currentX == 30) {
                    rect.set(currentX + baseX[6], 0, currentX + SCREEN_MARGIN + baseX[6] + stepCount + 6 * SCREEN_MARGIN, screenHeight);
                } else {
                    rect.set(currentX + SCREEN_MARGIN + baseX[6], 0, currentX + SCREEN_MARGIN + baseX[6] + stepCount + 5 * SCREEN_MARGIN, screenHeight);
                }
                waveCanvas.drawBitmap(backMap, rect, rect, null);
            }
        }
        int step = 0;
        if (waveDisplayType == 2) {
            for (int k = 0; k < lockStep; k++) {
                DrawLeadWave(dot13.get(k), 5, currentX + step);
                step++;
            }
        } else {
            for (int k = 0; k < lockStep; k++) {
                DrawLeadWave(dot0.get(k), 0, currentX + step);
                DrawLeadWave(dot1.get(k), 1, currentX + step);
                DrawLeadWave(dot2.get(k), 2, currentX + step);
                DrawLeadWave(dot3.get(k), 3, currentX + step);
                DrawLeadWave(dot4.get(k), 4, currentX + step);
                DrawLeadWave(dot5.get(k), 5, currentX + step);
                DrawLeadWave(dot6.get(k), 6, currentX + step);
                DrawLeadWave(dot7.get(k), 7, currentX + step);
                DrawLeadWave(dot8.get(k), 8, currentX + step);
                DrawLeadWave(dot9.get(k), 9, currentX + step);
                DrawLeadWave(dot10.get(k), 10, currentX + step);
                DrawLeadWave(dot11.get(k), 11, currentX + step);
                step++;
            }
        }

        if (stepCount > 0) {
            canvas = surfaceHolder.lockCanvas();
            if (canvas != null) {
                canvas.drawColor(getResources().getColor(R.color.ecg_back_color));
                canvas.drawBitmap(waveMap, 0, 0, null);
                DrawWaveTag();
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }
    }

    /**
     * 波形图的具体画法
     **/
    private void DrawLeadWave(int da, int leadNum, int offset) {
        int y;
        int oldX;
        int i;
        oldX = offset;
        if (baseLineState == -1) {
            mPaint.setColor(getResources().getColor(R.color.ecg_line_init));
        } else {
            mPaint.setColor(Color.BLUE);
        }
        i = offset + 1;
        if (isFirstDrawWave[leadNum]) {
            if (da == Integer.MAX_VALUE) {
                if (waveIsPace) {
                    pacePaint.setColor(Color.RED);
                } else {
                    pacePaint.setColor(Color.TRANSPARENT);
                }
                y = oldY[leadNum];
                waveCanvas.drawLine(oldX + SCREEN_MARGIN + baseX[leadNum], oldY[leadNum] - 15,// + baseY[leadNum]
                        oldX + SCREEN_MARGIN + baseX[leadNum], oldY[leadNum] + 15,// + baseY[leadNum]
                        pacePaint);
            } else {
                int mvValue = (-da * ECG_SINGLE_SPAN_SIZE * 20 / value);
                int finalDrawMvValueY = (mvValue / waveGain) * screenSize;
                y = (baseY[leadNum] + finalDrawMvValueY); //getYLead(leadNum, da); //192  192 * 2
                waveCanvas.drawLine(oldX + SCREEN_MARGIN + baseX[leadNum], oldY[leadNum],// + baseY[leadNum]
                        i + SCREEN_MARGIN + baseX[leadNum], y,// + baseY[leadNum]
                        mPaint);
                Log.e(TAG, "" + (-da) / (value * waveGain));
            }
        } else {
            isFirstDrawWave[leadNum] = true;
            if (da == Integer.MAX_VALUE) {
                y = oldY[leadNum];
            } else {
                // -da 是原始的心电数据  / 10500得到电压值 *5 计算出增益是一的时候的坐标 *20 是增益是20的坐标
                int mvValueDistance = (-da * ECG_SINGLE_SPAN_SIZE * 20 / value);
                int drawEcgY = (mvValueDistance / waveGain) * screenSize;
                y = (baseY[leadNum] + drawEcgY);
            }
        }
        oldY[leadNum] = y;
    }

    /****
     * 在surfaceview上绘制姿势提示图片
     */
    private void drawBodyLeadReadState() {
        //获取surfaceView对应的画板
        canvas = surfaceHolder.lockCanvas();
        if (canvas != null) {
            //设置画板颜色为黑色
            canvas.drawColor(Color.BLACK);
            Rect rect = new Rect();
            //设置姿势图示图片的绘制位置
            rect.set((int) side / 2, 0, (int) (side / 2 + bodyPercentW), screenHeight);//(int)bodyPercentW
            canvas.drawBitmap(bodyLeadMap, null, rect, null);
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }

    /***
     * 绘制导联状态的小圆点
     */
    private void drawBodyLeadSpot() {
        int circleRadius = 6 * screenSize;
        redPaint.setAntiAlias(false);
        greenPaint.setAntiAlias(false);
        canvas = surfaceHolder.lockCanvas();
        if (canvas != null) {
            canvas.drawColor(Color.BLACK);
            Rect rect = new Rect();
            rect.set((int) side / 2, 0, (int) (side / 2 + bodyPercentW), screenHeight);//(int)bodyPercentW
            canvas.drawBitmap(bodyLeadMap, null, rect, null);
            for (int i = 0; i < bodyLeaData.length; i++) {
                if (bodyLeaData[i]) canvas.drawCircle(leadX[i], leadY[i], circleRadius, redPaint);
                else canvas.drawCircle(leadX[i], leadY[i], circleRadius, greenPaint);
            }
            canvas.drawCircle(leadX[9], leadY[9], circleRadius, greenPaint);
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }

    /**
     * 确定抽点
     **/
    private void initSampleDot() {
        sampleDot = new SampleDotIntNew[LEAD_NUM + 1];
        for (int i = 0; i < LEAD_NUM + 1; i++) {
            sampleDot[i] = new SampleDotIntNew(500);//, 126 / (waveSpeed + 1)
        }
        if (screenSize == 1) {//手机分辨率小于等于800时
            initDeSampleDot(125 / (waveSpeed + 1));
        } else {
            initDeSampleDot(248 / (waveSpeed + 1));
        }
    }

    private void initDeSampleDot(int desDot) {
        for (int i = 0; i < LEAD_NUM + 1; i++) {
            //设置每次要绘制的点的个数
            sampleDot[i].setDesSampleDot(desDot);
        }
    }

    /**
     * 绘制心电图的背景
     **/
    private void DrawBackBmp() {
        if (waveDisplayType == 0) {
            for (int i = 0; i < LEAD_NUM; i++) {

                baseY[i] = screenHeight / LEAD_NUM * 2 * (i % 6 + 1) - 30;
            }
            for (int i = 0; i < LEAD_NUM; i++) {
                if (i < 6) {
                    baseX[i] = 0;
                } else {
                    baseX[i] = screenWidth / 2 + SCREEN_MARGIN;
                }
            }
        } else {
            for (int i = 0; i < LEAD_NUM; i++) {
                baseY[i] = screenHeight / LEAD_NUM * (i % 12 + 1) - 20;
            }
            for (int i = 0; i < LEAD_NUM; i++) {
                baseX[i] = 0;
            }
        }
        canvas = new Canvas(backMap);
        canvas.drawColor(getResources().getColor(R.color.white));
        // 该方法的参数控制的是背景的每个小格子的宽度
        DrawVerticalLine(screenSize * ECG_SINGLE_SPAN_SIZE);
        DrawHorizontalLine(screenSize * ECG_SINGLE_SPAN_SIZE);
        if (waveDisplayType == 0) {
            DrawWaveGain(0, baseY[2] + ECG_RULER_MARGIN_SIZE);
            DrawWaveGain(baseX[8], baseY[2] + ECG_RULER_MARGIN_SIZE);
        } else {
            DrawWaveGain(0, baseY[5] + ECG_RULER_MARGIN_SIZE);
        }
        canvas = new Canvas(waveMap);
        canvas.drawBitmap(backMap, 0, 0, null);
    }

    // 绘制标尺
    private void DrawWaveGain(int x, int y) {
        greenPaint.setStrokeWidth(1);
        canvas.drawLine(x + SCREEN_MARGIN, y + 5, x + SCREEN_MARGIN + 5, y + 5, greyPaint);

        canvas.drawLine(x + SCREEN_MARGIN + 5, y + 5, x + SCREEN_MARGIN + 5, y - (20 / waveGain) * 5 * screenSize + 5, greyPaint);

        canvas.drawLine(x + SCREEN_MARGIN + 5, y - (20 / waveGain) * 5 * screenSize + 5, x + SCREEN_MARGIN + 5 + 10, y - (20 / waveGain) * 5 * screenSize + 5, greyPaint);

        canvas.drawLine(x + SCREEN_MARGIN + 5 + 10, y + 5, x + SCREEN_MARGIN + 5 + 10, y - (20 / waveGain) * 5 * screenSize + 5, greyPaint);

        canvas.drawLine(x + SCREEN_MARGIN + 5 + 10, y + 5, x + SCREEN_MARGIN + 5 + 10 + 5, y + 5, greyPaint);
    }

    /**
     * 画水平线条
     **/
    private void DrawVerticalLine(int step) {
        int j = 0;
        for (int i = 0; i <= screenHeight; i += step) {
            if (j == 0) {
                canvas.drawLine(SCREEN_MARGIN, i + SCREEN_MARGIN, screenWidth + step, i + SCREEN_MARGIN, topGridPaint);
            } else {
                canvas.drawLine(SCREEN_MARGIN, i + SCREEN_MARGIN, screenWidth + step, i + SCREEN_MARGIN, subGridPaint);
            }
            j++;
            if (j >= 5) j = 0;
        }

    }

    /**
     * 画垂直线条
     **/
    private void DrawHorizontalLine(int step) {
        int j = 0;
        for (int i = 0; i <= screenWidth; i += step) {
            if (j == 0) {
                canvas.drawLine(i + SCREEN_MARGIN, SCREEN_MARGIN, i + SCREEN_MARGIN, screenHeight + step, topGridPaint);
            } else {
                canvas.drawLine(i + SCREEN_MARGIN, SCREEN_MARGIN, i + SCREEN_MARGIN, screenWidth + step, subGridPaint);
            }
            j++;
            if (j >= 5) j = 0;
        }
    }

    /**
     * 画波形名称 ji
     **/
    private void DrawWaveTag() {
        greyPaint.setTextSize(18f);
        int mY;
        if (waveDisplayType == 0) {
            mY = 8;
        } else {
            mY = 5;
        }
        if (waveDisplayType == 2) {
            canvas.drawText(leadName[waveSingleDisplaySwitch], baseX[3] + 10, baseY[3] - mY, greyPaint);
        } else {
            for (int i = 0; i < LEAD_NUM; i++) {
                canvas.drawText(leadName[i], baseX[i] + 10, baseY[i] - mY, greyPaint);
            }
        }
    }


    private void clearSaveCache() {
        baseLineState = -1;
        bufferAuto.clear();
        saveCount = 0;
    }

    /**
     * 清除缓存空间
     **/
    private void clearCache() {
        synchronized (ecgDataBuffer) {
            ecgDataBuffer.clear();
        }
        currentX = 30;
    }


    @Override
    public void getOriginalEcgData(int[] data, int len, boolean[] leadState, boolean pace, int packageId) {

        //导联状态的检测的整体的逻辑是 第一次线检测一下 后续的状态检测都是通过保存导联状态数据
        //之后通过timer定时绘制
        //是否跳过导联检测
        if (!bodyLeadStateSkip) {
            for (int i = 0; i < leadState.length; i++) {
                //判断是否有导联脱落
                if (leadState[i]) {
                    //一个表示导联线是否脱落的boolean true 的时候是脱落
                    bodyLeadState = true;
                    isRestartDraw = true;
                    //记录导联线是否全部联通
                    bodyLeadState_GREEN_First = 0;
                    break;
                }
                bodyLeadState = false;
                bodyLeadState_GREEN_First += 1;
            }


            //后续过来的数据如果是导联脱落语音提示
            //通过timer来去驱动重绘制
            if (bodyLeadState) {//导联脱落，绘制导联图；

                ////导联脱落标识
                if (!bodyLeadStateOff) {
                    handler.sendEmptyMessage(BODY_LEAD_STATE_OFF);
                    long current = System.currentTimeMillis();
                    if ((current - bodyLeadStateStart) < 2000) {
                        handler.removeMessages(DRAW_BODY_LEAD_STATE);
                    }
                    bodyLeadStateOff = true;
                    Log.e(TAG, "首次导联脱落");
                }
                for (int i = 0; i < leadState.length; i++) {
                    bodyLeaData[i] = leadState[i];
                }
                clearCache();
                clearSaveCache();
                return;
            }

            if (bodyLeadState_GREEN_First == 9) {//首次连接成功后，显示导联连接成功两秒中
                bodyLeadStateOff = false;
                bodyLeadStateStart = System.currentTimeMillis();
                isDrawECGWave = true;
                bodyLeadState_GREEN = true;
                handler.sendEmptyMessage(DRAW_BODY_LEAD_START);

                for (int i = 0; i < leadState.length; i++) {
                    bodyLeaData[i] = leadState[i];
                }
                handler.sendEmptyMessageDelayed(DRAW_BODY_LEAD_STATE, 2000);
                return;
            }
            if (bodyLeadState_GREEN_First > 50000) {//防止数据太大
                bodyLeadState_GREEN_First = 27;
            }
        } else {
            //导联线的状态 脱落为true
            bodyLeadState = false;
            //导联线首次全部连接上为true
            bodyLeadState_GREEN = false;
            //绘制开关
            isDrawECGWave = false;
        }

        //心电数据滤波
        ecgFilter.filter(data, 1, 12);
        //data[1] -= 8000;
        //判断基线是否稳定
        if (baseLineState == -1) {
            //通过滤波工具类获取基线状态
            baseLineState = ecgFilter.isBaseLineStable(data, 1, 12);
        }
        //获取心率
        int heart = hrDetect.hrDetect(data, 1, 12);
        //心率合法
        if (heart > 0) {
            //音频播放的处理
            if (isPlaySound) {
                soundPool.play(soundPoolId[0], 1.0F, 1.0F, 1, 0, 1.0F);
            }
            Message msg = handler.obtainMessage(HEART_NUM);
            msg.obj = heart;
            handler.sendMessage(msg);
        }
        if (pace) {
            drawDataList.add(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE});
        } else {
            drawDataList.add(data);
        }
        //需要保存文件并且滤波稳定的时候处理数据
        if (isSaveFile && baseLineState == 0) {//保存的数据需要滤波处理
            if (saveFileType == 2) {
                buffer24H.add(data[waveSingleDisplaySwitch]);
            } else {
                if (saveFileType == 0) {
                    if (pace) {
                        //起搏是通过向绘制的数据集合中添加指定的数据实现的
                        bufferAuto.add(new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE});
                    } else {
                        bufferAuto.add(data);
                    }
                } else {
                    if (pace) {
                        buf0.add(Integer.MAX_VALUE);
                        buf1.add(Integer.MAX_VALUE);
                        buf2.add(Integer.MAX_VALUE);
                        buf3.add(Integer.MAX_VALUE);
                        buf4.add(Integer.MAX_VALUE);
                        buf5.add(Integer.MAX_VALUE);
                        buf6.add(Integer.MAX_VALUE);
                        buf7.add(Integer.MAX_VALUE);
                        buf8.add(Integer.MAX_VALUE);
                        buf9.add(Integer.MAX_VALUE);
                        buf10.add(Integer.MAX_VALUE);
                        buf11.add(Integer.MAX_VALUE);
                    } else {
                        buf0.add(data[0]);
                        buf1.add(data[1]);
                        buf2.add(data[2]);
                        buf3.add(data[3]);
                        buf4.add(data[4]);
                        buf5.add(data[5]);
                        buf6.add(data[6]);
                        buf7.add(data[7]);
                        buf8.add(data[8]);
                        buf9.add(data[9]);
                        buf10.add(data[10]);
                        buf11.add(data[11]);
                    }

                }
            }
            saveCount++;
            //更新测量时间
            if (saveCount % 500 == 0) {
                timeSecondCount = saveCount / 500;
                handler.sendEmptyMessage(SAVE_PDF_XML_TIMECOUNT);
            }
            //通过这个控制采集多久时间才保存数据
            if (saveCount == saveFileSecondCount) {
                if (saveFileType == 2) {
                    Integer[] data24H = new Integer[buffer24H.size()];
                    buffer24H.toArray(data24H);
                    synchronized (saveFile24HThread.queue) {
                        saveFile24HThread.addToQueue(data24H);
                    }
                    buffer24H.clear();
                    saveCount = 0;
                    saveManualMinuteCount += 1;
                    if (saveManualMinuteCount == 60 * 2 * 24) {
                        Message message = Message.obtain();
                        message.what = MANUAL_ECG_AUTO_FINISH_FLAG;
                        message.obj = getResources().getString(R.string.activity_ecgmeasure_24hours);
                        handler.sendMessage(message);
                    }
                } else if (saveFileType == 0) {
                    List<int[]> bufferLists = bufferAuto;
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("FilterBase", dataBinding.ecgMeasureFilterTwo.getText().toString());
                    map.put("FilterMC", dataBinding.ecgMeasureFilterThree.getText().toString());
                    map.put("FilterAC", dataBinding.ecgMeasureFilterOne.getText().toString());
                    map.put("FilterLP", dataBinding.ecgMeasureFilterFour.getText().toString());
                    map.put("waveGain", waveGain);
                    map.put("waveSpeed", waveSpeed);
                    map.put("waveSingleDisplay_Switch", waveSingleDisplaySwitch);
                    map.put("waveDisplayType", waveDisplayType);
                    map.put("ecgDataBuffer", bufferLists);
                    map.put("ecg2DeviceData_time", manualEcgStartTime);
                    map.put("saveFileManualCount", saveManualMinuteCount);
                    map.put("timeSecondCount", timeSecondCount);
                    map.put("PAT_ID", patientId);
                    map.put("PAT_AGE", patientAge);
                    map.put("PAT_GENDER", patientGender);
                    map.put("PAT_NAME", patientName);
                    stopDataSource();
                    saveFileAutoThread.startAutoTask(map);
                    isSaveFile = false;
                    isDrawECGWave = true;

                } else if (saveFileType == 1) {
                    Integer[] d0 = new Integer[buf0.size()];
                    buf0.toArray(d0);
                    Integer[] d1 = new Integer[buf1.size()];
                    buf1.toArray(d1);
                    Integer[] d2 = new Integer[buf2.size()];
                    buf2.toArray(d2);
                    Integer[] d3 = new Integer[buf3.size()];
                    buf3.toArray(d3);
                    Integer[] d4 = new Integer[buf4.size()];
                    buf4.toArray(d4);
                    Integer[] d5 = new Integer[buf5.size()];
                    buf5.toArray(d5);
                    Integer[] d6 = new Integer[buf6.size()];
                    buf6.toArray(d6);
                    Integer[] d7 = new Integer[buf7.size()];
                    buf7.toArray(d7);
                    Integer[] d8 = new Integer[buf8.size()];
                    buf8.toArray(d8);
                    Integer[] d9 = new Integer[buf9.size()];
                    buf9.toArray(d9);
                    Integer[] d10 = new Integer[buf10.size()];
                    buf10.toArray(d10);
                    Integer[] d11 = new Integer[buf11.size()];
                    buf11.toArray(d11);
                    clearManualBuffer();
                    Map<String, Object> map = new HashMap<>();
                    map.put("ecgDataBuffer0", d0);
                    map.put("ecgDataBuffer1", d1);
                    map.put("ecgDataBuffer2", d2);
                    map.put("ecgDataBuffer3", d3);
                    map.put("ecgDataBuffer4", d4);
                    map.put("ecgDataBuffer5", d5);
                    map.put("ecgDataBuffer6", d6);
                    map.put("ecgDataBuffer7", d7);
                    map.put("ecgDataBuffer8", d8);
                    map.put("ecgDataBuffer9", d9);
                    map.put("ecgDataBuffer10", d10);
                    map.put("ecgDataBuffer11", d11);
                    map.put("ecg2DeviceData_time", manualEcgStartTime);
                    map.put("saveFileManualCount", saveManualMinuteCount);
                    map.put("timeSecondCount", timeSecondCount);
                    saveFileManualThread.addToQueue(map);
                    saveCount = 0;
                    saveManualMinuteCount += 1;
                    //手动测量 时间为2小时
                    if (saveManualMinuteCount == 60 * 2) {
                        Message message = Message.obtain();
                        message.what = MANUAL_ECG_AUTO_FINISH_FLAG;
                        message.obj = "手动测量2小时";
                        handler.sendMessage(message);
                    }
                }
            }
        }

        if (isDrawECGWave) {//绘制开关
            return;
        }
        //获取8次数据存储到一个缓存中
        callData_count++;
        if (callData_count == 8) {
            synchronized (ecgDataBuffer) {
                ecgDataBuffer.addAll(drawDataList);
                drawDataList.clear();
            }
            callData_count = 0;
        }
    }


    public void getBleEcgData(int[] ecgDataReal, boolean[] leadState, String lead) {
        if (bleSaveEnough) {
            return;
        }
        if (!bodyLeadStateSkip) {
            for (int i = 0; i < leadState.length; i++) {
                if (leadState[i]) {//有导联脱落
                    bodyLeadState = true;
                    isRestartDraw = true;
                    bodyLeadState_GREEN_First = 0;
                    break;
                }
                bodyLeadState = false;
                bodyLeadState_GREEN_First++;
            }
            if (bodyLeadState) {//导联脱落，绘制导联图；
                if (!bodyLeadStateOff) {
                    handler.sendEmptyMessage(BODY_LEAD_STATE_OFF);
                    long current = System.currentTimeMillis();
                    if ((current - bodyLeadStateStart) < 2000) {
                        handler.removeMessages(DRAW_BODY_LEAD_STATE);
                    }
                    bodyLeadStateOff = true;
                }
                System.arraycopy(leadState, 0, bodyLeaData, 0, leadState.length);
                clearCache();
                clearSaveCache();
                return;
            }
            if (bodyLeadState_GREEN_First == 10) {//首次连接成功后，显示导联连接成功两秒中
                bodyLeadStateOff = false;
                bodyLeadStateStart = System.currentTimeMillis();
                isDrawECGWave = true;
                bodyLeadState_GREEN = true;
                Log.e("TAG", "导联连接成功");
                handler.sendEmptyMessage(DRAW_BODY_LEAD_START);
                System.arraycopy(leadState, 0, bodyLeaData, 0, leadState.length);
                handler.sendEmptyMessageDelayed(DRAW_BODY_LEAD_STATE, 2000);
                return;
            }
            if (bodyLeadState_GREEN_First > 50000) {//防止数据太大
                bodyLeadState_GREEN_First = 30;
            }
        } else {
            bodyLeadState = false;
            bodyLeadState_GREEN = false;
            isDrawECGWave = false;
        }
        ecgFilter.filter(ecgDataReal, 1, 12);
        if (baseLineState == -1) {// && !isCheckBodyLead
            baseLineState = ecgFilter.isBaseLineStable(ecgDataReal, 1, 12);
        }
        int heart = hrDetect.hrDetect(ecgDataReal, 1, 12);
        if (heart > 0) {
            try {
                if (isPlaySound) {
                    soundPool.play(soundPoolId[0], 1.0F, 1.0F, 1, 0, 1.0F);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            Message msg = handler.obtainMessage(HEART_NUM);
            msg.obj = heart;
            handler.sendMessage(msg);
        }
        if (isSaveFile && baseLineState == 0) {//保存的数据需要滤波处理
            if (saveFileType == 2) {
                buffer24H.add(ecgDataReal[waveSingleDisplaySwitch]);
            } else {
                if (saveFileType == 0) {
                    bufferAuto.add(ecgDataReal);
                } else {
                    buf0.add(ecgDataReal[0]);
                    buf1.add(ecgDataReal[1]);
                    buf2.add(ecgDataReal[2]);
                    buf3.add(ecgDataReal[3]);
                    buf4.add(ecgDataReal[4]);
                    buf5.add(ecgDataReal[5]);
                    buf6.add(ecgDataReal[6]);
                    buf7.add(ecgDataReal[7]);
                    buf8.add(ecgDataReal[8]);
                    buf9.add(ecgDataReal[9]);
                    buf10.add(ecgDataReal[10]);
                    buf11.add(ecgDataReal[11]);
                }
            }
            saveCount++;
            if (saveCount % 500 == 0) {
                timeSecondCount = saveCount / 500;
                handler.sendEmptyMessage(SAVE_PDF_XML_TIMECOUNT);
            }
            if (saveCount == saveFileSecondCount) {
                if (saveFileType == 2) {
                    Integer[] data24H = new Integer[buffer24H.size()];
                    buffer24H.toArray(data24H);
                    synchronized (saveFile24HThread.queue) {
                        saveFile24HThread.addToQueue(data24H);
                    }
                    buffer24H.clear();
                    saveCount = 0;
                    saveManualMinuteCount += 1;
                } else if (saveFileType == 0) {
                    List<int[]> bufferLists = bufferAuto;
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("FilterBase", dataBinding.ecgMeasureFilterTwo.getText().toString());
                    map.put("FilterMC", dataBinding.ecgMeasureFilterThree.getText().toString());
                    map.put("FilterAC", dataBinding.ecgMeasureFilterOne.getText().toString());
                    map.put("FilterLP", dataBinding.ecgMeasureFilterFour.getText().toString());
                    map.put("waveGain", waveGain);
                    map.put("waveSpeed", waveSpeed);
                    map.put("waveSingleDisplay_Switch", waveSingleDisplaySwitch);
                    map.put("waveDisplayType", waveDisplayType);
                    map.put("ecgDataBuffer", bufferLists);
                    map.put("ecg2DeviceData_time", manualEcgStartTime);
                    map.put("saveFileManualCount", saveManualMinuteCount);
                    map.put("timeSecondCount", timeSecondCount);
                    map.put("PAT_ID", patientId);
                    map.put("PAT_AGE", patientAge);
                    map.put("PAT_GENDER", patientGender);
                    map.put("PAT_NAME", patientName);
                    stopDataSource();
                    bleSaveEnough = true;
                    saveFileAutoThread.startAutoTask(map);
                    isSaveFile = false;
                    isDrawECGWave = true;
                } else if (saveFileType == 1) {
                    Integer[] d0 = new Integer[buf0.size()];
                    buf0.toArray(d0);
                    Integer[] d1 = new Integer[buf1.size()];
                    buf1.toArray(d1);
                    Integer[] d2 = new Integer[buf2.size()];
                    buf2.toArray(d2);
                    Integer[] d3 = new Integer[buf3.size()];
                    buf3.toArray(d3);
                    Integer[] d4 = new Integer[buf4.size()];
                    buf4.toArray(d4);
                    Integer[] d5 = new Integer[buf5.size()];
                    buf5.toArray(d5);
                    Integer[] d6 = new Integer[buf6.size()];
                    buf6.toArray(d6);
                    Integer[] d7 = new Integer[buf7.size()];
                    buf7.toArray(d7);
                    Integer[] d8 = new Integer[buf8.size()];
                    buf8.toArray(d8);
                    Integer[] d9 = new Integer[buf9.size()];
                    buf9.toArray(d9);
                    Integer[] d10 = new Integer[buf10.size()];
                    buf10.toArray(d10);
                    Integer[] d11 = new Integer[buf11.size()];
                    buf11.toArray(d11);
                    clearManualBuffer();
                    Map<String, Object> map = new HashMap<>();
                    map.put("ecgDataBuffer0", d0);
                    map.put("ecgDataBuffer1", d1);
                    map.put("ecgDataBuffer2", d2);
                    map.put("ecgDataBuffer3", d3);
                    map.put("ecgDataBuffer4", d4);
                    map.put("ecgDataBuffer5", d5);
                    map.put("ecgDataBuffer6", d6);
                    map.put("ecgDataBuffer7", d7);
                    map.put("ecgDataBuffer8", d8);
                    map.put("ecgDataBuffer9", d9);
                    map.put("ecgDataBuffer10", d10);
                    map.put("ecgDataBuffer11", d11);
                    map.put("ecg2DeviceData_time", manualEcgStartTime);
                    map.put("saveFileManualCount", saveManualMinuteCount);
                    map.put("timeSecondCount", timeSecondCount);
                    saveFileManualThread.addToQueue(map);
                    saveCount = 0;
                    saveManualMinuteCount += 1;

                }
            }
        }
        if (isDrawECGWave) {//绘制开关3
            return;
        }
        drawDataList.add(ecgDataReal);
        callData_count++;
        if (callData_count > 15) {
            synchronized (ecgDataBuffer) {
                ecgDataBuffer.addAll(drawDataList);
                drawDataList.clear();
            }
            callData_count = 0;
        }
    }

    class DrawWaveTimeTask extends TimerTask {
        @Override
        public void run() {

            if (bodyLeadState || bodyLeadState_GREEN) {//导联脱落；首次导联状态全部连接时
                waveCanvas.drawColor(Color.BLACK);
                drawBodyLeadSpot();
                return;
            }
            //是否需要重新绘制
            if (isRestartDraw) {
                hrDetect.initHr(3495.2533333f * 3);
                DrawBackBmp();
                isRestartDraw = false;
            }
            //增益改变重新绘制背景
            if (waveGainChangeFlag) {
                DrawBackBmp();
                waveGainChangeFlag = false;
                currentX = 30;
            }
            //是否需要绘制心电图
            if (isDrawECGWave) {
                tempList.clear();
                return;
            }
            if (ecgDataBuffer.size() > (DRAW_STEP_SIZE)) {
                synchronized (ecgDataBuffer) {
                    int num = ecgDataBuffer.size();
                    for (int i = num - 1; i >= 0; i--) {
                        tempList.add(((LinkedList<int[]>) ecgDataBuffer).removeFirst());
                    }
                }
                SimpleDraw(tempList);
                tempList.clear();
            }
        }
    }

    /***
     * 自动结束蓝牙扫描
     */
    class FinishScanBlueToothTask extends TimerTask {
        @Override
        public void run() {
            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
                finish();
            }
        }
    }

    private void showFilterDialog() {
        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.current_filter_setting, findViewById(R.id.current_filter_dialog));
        hp_group = layout.findViewById(R.id.hp_group);
        mc_group = layout.findViewById(R.id.mc_group);
        ac_group = layout.findViewById(R.id.ac_group);
        lp_group = layout.findViewById(R.id.lp_group);
        if (FilterBase == 2) {
            ((RadioButton) hp_group.getChildAt(0)).setChecked(true);
        } else if (FilterBase == 3) {
            ((RadioButton) hp_group.getChildAt(1)).setChecked(true);
        } else if (FilterBase == 4) {
            ((RadioButton) hp_group.getChildAt(2)).setChecked(true);
        } else if (FilterBase == 1) {
            ((RadioButton) hp_group.getChildAt(3)).setChecked(true);
        }
        if (FilterMC == 12) {
            ((RadioButton) mc_group.getChildAt(0)).setChecked(true);
        } else if (FilterMC == 13) {
            ((RadioButton) mc_group.getChildAt(1)).setChecked(true);
        } else if (FilterMC == 14) {
            ((RadioButton) mc_group.getChildAt(2)).setChecked(true);
        } else if (FilterMC == 11) {
            ((RadioButton) mc_group.getChildAt(3)).setChecked(true);
        }
        if (FilterAC == 22) {
            ((RadioButton) ac_group.getChildAt(0)).setChecked(true);
        } else if (FilterAC == 23) {
            ((RadioButton) ac_group.getChildAt(1)).setChecked(true);
        } else if (FilterAC == 21) {
            ((RadioButton) ac_group.getChildAt(2)).setChecked(true);
        }
        if (FilterLP == 36) {//25hz
            ((RadioButton) lp_group.getChildAt(0)).setChecked(true);
        } else if (FilterLP == 35) {//40hz
            ((RadioButton) lp_group.getChildAt(1)).setChecked(true);
        } else if (FilterLP == 32) {//75hz
            ((RadioButton) lp_group.getChildAt(2)).setChecked(true);
        } else if (FilterLP == 33) {//100hz
            ((RadioButton) lp_group.getChildAt(3)).setChecked(true);
        } else if (FilterLP == 34) {//150hz
            ((RadioButton) lp_group.getChildAt(4)).setChecked(true);
        } else if (FilterLP == 31) {//OFF
            ((RadioButton) lp_group.getChildAt(5)).setChecked(true);
        }

        final AlertDialog.Builder imageDialog = new AlertDialog.Builder(this);
        imageDialog.setTitle(getResources().getString(R.string.dialog_filter_setting_title)).setIcon(android.R.drawable.btn_star).setView(layout);
        imageDialog.setPositiveButton(getResources().getString(R.string.dialog_filter_setting_btn_ok), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                //基线滤波选择
                if (R.id.hp_005hz == hp_group.getCheckedRadioButtonId()) {
                    FilterBase = 2;
                    dataBinding.ecgMeasureFilterTwo.setText("0.05Hz");
                } else if (R.id.hp_025hz == hp_group.getCheckedRadioButtonId()) {
                    FilterBase = 3;
                    dataBinding.ecgMeasureFilterTwo.setText("0.25Hz");
                } else if (R.id.hp_050hz == hp_group.getCheckedRadioButtonId()) {
                    FilterBase = 4;
                    dataBinding.ecgMeasureFilterTwo.setText("0.50Hz");
                } else if (R.id.hp_off == hp_group.getCheckedRadioButtonId()) {
                    FilterBase = 1;
                    dataBinding.ecgMeasureFilterTwo.setText("OFF");
                }
                //肌电滤波选择
                if (R.id.mc_25hz == mc_group.getCheckedRadioButtonId()) {
                    FilterMC = 12;
                    dataBinding.ecgMeasureFilterThree.setText("25Hz");
                } else if (R.id.mc_35hz == mc_group.getCheckedRadioButtonId()) {
                    FilterMC = 13;
                    dataBinding.ecgMeasureFilterThree.setText("35Hz");
                } else if (R.id.mc_45hz == mc_group.getCheckedRadioButtonId()) {
                    FilterMC = 14;
                    dataBinding.ecgMeasureFilterThree.setText("45Hz");
                } else if (R.id.mc_off == mc_group.getCheckedRadioButtonId()) {
                    FilterMC = 11;
                    dataBinding.ecgMeasureFilterThree.setText("OFF");
                }
                //工作滤波选择
                if (R.id.ac_50hz == ac_group.getCheckedRadioButtonId()) {
                    FilterAC = 22;
                    dataBinding.ecgMeasureFilterOne.setText("50Hz");
                } else if (R.id.ac_60hz == ac_group.getCheckedRadioButtonId()) {
                    FilterAC = 23;
                    dataBinding.ecgMeasureFilterOne.setText("60Hz");
                } else if (R.id.ac_off == ac_group.getCheckedRadioButtonId()) {
                    FilterAC = 21;
                    dataBinding.ecgMeasureFilterOne.setText("OFF");
                }
                //低通滤波
                if (R.id.lp_75hz == lp_group.getCheckedRadioButtonId()) {
                    FilterLP = 32;
                    dataBinding.ecgMeasureFilterFour.setText("75Hz");
                } else if (R.id.lp_100hz == lp_group.getCheckedRadioButtonId()) {
                    FilterLP = 33;
                    dataBinding.ecgMeasureFilterFour.setText("100Hz");
                } else if (R.id.lp_150hz == lp_group.getCheckedRadioButtonId()) {
                    FilterLP = 34;
                    dataBinding.ecgMeasureFilterFour.setText("150Hz");
                } else if (R.id.lp_off == lp_group.getCheckedRadioButtonId()) {
                    FilterLP = 31;
                    dataBinding.ecgMeasureFilterFour.setText("OFF");
                } else if (R.id.lp_40hz == lp_group.getCheckedRadioButtonId()) {
                    FilterLP = 35;
                    dataBinding.ecgMeasureFilterFour.setText("40hz");
                } else if (R.id.lp_25hz == lp_group.getCheckedRadioButtonId()) {
                    FilterLP = 36;
                    dataBinding.ecgMeasureFilterFour.setText("25Hz");
                }

                ecgFilter.initFilter(FilterBase, FilterMC, FilterAC, FilterLP);
                hrDetect.initHr(3495.2533333f * 3);
                isDrawECGWave = false;
                initSaveData();
                currentX = 30;
                arg0.dismiss();
            }
        });
        imageDialog.create();
        imageDialog.setCancelable(false);
        imageDialog.show();
    }

    /***
     * 初始化绘制时候存储数据的多少的相关参数
     */
    private void initSaveData() {
        dataBinding.ecgMeasureStartTime.setText("");
        //自动测试10s 5000个数据
        if (saveFileType == 0) {
            saveFileSecondCount = 500 * 10;
            isSaveFile = true;
            saveCount = 0;
            bufferAuto.clear();
            //手动测量60秒
        } else if (saveFileType == 1) {
            saveFileSecondCount = 500 * 60;
            saveCount = 0;
            initManualBuffer();
        }
    }

    private void initManualBuffer() {
        buf0 = new ArrayList<>();
        buf1 = new ArrayList<>();
        buf2 = new ArrayList<>();
        buf3 = new ArrayList<>();
        buf4 = new ArrayList<>();
        buf5 = new ArrayList<>();
        buf6 = new ArrayList<>();
        buf7 = new ArrayList<>();
        buf8 = new ArrayList<>();
        buf9 = new ArrayList<>();
        buf10 = new ArrayList<>();
        buf11 = new ArrayList<>();
    }

    private void clearManualBuffer() {
        buf0.clear();
        buf1.clear();
        buf2.clear();
        buf3.clear();
        buf4.clear();
        buf5.clear();
        buf6.clear();
        buf7.clear();
        buf8.clear();
        buf9.clear();
        buf10.clear();
        buf11.clear();
    }

    private void invokeFinish(String xmlPath) {
        String[] filePath = xmlPath.split("\\|");
        writeContentToFile(adb_command_dir, adb_command_typec.toCharArray());
        Intent invokeIntent = new Intent("com.wehealth.ecg.report");
        Bundle bundle = new Bundle();
        bundle.putString("ecg_file_path", filePath[0]);
        bundle.putString("ecg_file_pdf_path", filePath[1]);
        invokeIntent.putExtras(bundle);
        startActivity(invokeIntent);
        finish();
    }


    @Override
    protected void onResume() {
        super.onResume();
        if (DataServiceIsRunning) {
            isDrawECGWave = false;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (DataServiceIsRunning) {
            isDrawECGWave = true;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        soundPool.release();
        MainHandler.INSTANCE.removeAll();
        writeContentToFile(adb_command_dir, adb_command_typec.toCharArray());
        stopDataSource();

    }
}

